/**
 * 表单匹配选择器
 */
import React from 'react';
import classNames from 'classnames';
import { Button, Input, Form, DatePicker, Select, InputNumber, Icon } from 'antd';
import { trims, types, isEmptyParam } from '@/utils/utils';
import { datePickRanges, disabledRangeDate } from '@/components/CreateForm/utils';
import { StateType } from '@/common-typings';
import { WithButtonAuth } from '@/components/CreateTable/TableTool';

export const Selector = (
  item: StateType,
  formConfig: StateType,
  that: StateType,
  exclude = false,
) => {
  const { isMobile, form } = that.props;
  const { getFieldDecorator, setFieldsValue, getFieldValue } = form;

  // 初始化常用的变量
  const label = item.type === 'button' ? '' : item.options.name;
  const placeholder = item.options.placeholder || '';
  const allowClear = item.options.allowClear !== undefined ? item.options.allowClear : true;
  const disabled = item.options.disabled || false;
  const width =
    (formConfig.isPopup || isMobile) && !formConfig.noDrawer ? '100%' : item.options.width || 180;
  const size = item.size || 'default';
  const autoComplete = item.default === 'password' ? 'new-password' : 'off';

  // 用于替换配置
  const config = item.config || {};

  // 去除输入框前后的空格
  const trimsValue = (value: string) => {
    if (value !== '' && value !== null) {
      setFieldsValue({ [item.id]: trims(value) });
    }
  };

  // 获取每一项的规则
  const getFieldParams = () => {
    let result = {
      validateFirst: true,
      rules: formConfig.rules && !item.options.disabled ? formConfig.rules[item.id] : [],
    };

    if (!isEmptyParam(item.options.value)) {
      result = Object.assign(result, { initialValue: item.options.value });
    }
    return result;
  };

  // 声明返回值变量
  let results;

  switch (item.type) {
    // 按钮
    case 'button': {
      const htmlType = ['submit'].filter(i => i === item.id)[0] || 'button';
      const buttonLoadingKey = ['submit', 'export'].filter(i => i === item.id)[0];
      const loading = buttonLoadingKey ? formConfig[`${buttonLoadingKey}Loading`] : false;
      results = (
        <WithButtonAuth
          {...item.options}
          size={size}
          loading={loading}
          block
          style={item.style || {}}
          htmlType={htmlType}
          auth={item.options.auth || true}
          onClick={(e: any) => {
            e.preventDefault();
            // 判断子项中是否有回调方法
            that.beforeSearchCallBack(item.id, item.handle);
          }}
          {...config}
        >
          {item.options.name}
        </WithButtonAuth>
      );
      break;
    }

    // 输入框
    case 'input': {
      // 增加输入框前缀
      let addonBefore;
      if (item.options.addonBefore && types(item.options.addonBefore) === 'string') {
        const filterItem = formConfig.config.filter(
          (i: StateType) => i.id === item.options.addonBefore,
        )[0];
        if (filterItem) {
          addonBefore = Selector(filterItem, formConfig, that, true);
        } else {
          ({ addonBefore } = item.options);
        }
      }
      // input 原生事件enter调用了submit，不用单独增加方法
      results = getFieldDecorator(item.id, getFieldParams())(
        <Input
          style={item.style || { width }}
          disabled={disabled}
          placeholder={placeholder}
          type={item.default || 'text'}
          size={size}
          allowClear={!item.options.disabled && allowClear}
          addonBefore={addonBefore}
          onBlur={e => trimsValue(e.target.value)}
          autoComplete={autoComplete}
          {...config}
        />,
      );
      break;
    }

    case 'input-number': {
      results = getFieldDecorator(item.id, getFieldParams())(
        <InputNumber
          style={item.style || { width }}
          disabled={disabled}
          placeholder={item.options.placeholder || ''}
          precision={2}
          min={item.options.min || 0}
          size={size}
          {...config}
        />,
      );
      break;
    }

    // 金额范围组件
    case 'input-number-group': {
      const prev = formConfig.config.filter((i: StateType) => i.id === item.options.prev)[0];
      const next = formConfig.config.filter((i: StateType) => i.id === item.options.next)[0];
      if (prev && next) {
        const prevValue = getFieldValue(prev.id);
        const nextValue = getFieldValue(next.id);
        // 限制后面输入框值必须大于等于前面的值
        if (nextValue && prevValue > nextValue) {
          next.options.min = prevValue;
        }
        results = (
          <React.Fragment>
            {Selector(prev, formConfig, that)}
            {<span style={{ position: 'relative', left: '-9px' }}>-</span>}
            {Selector(next, formConfig, that)}
          </React.Fragment>
        );
      }
      break;
    }

    // textarea
    case 'textarea': {
      const { TextArea } = Input;
      results = getFieldDecorator(item.id, getFieldParams())(
        <TextArea
          style={item.style || { width }}
          disabled={disabled}
          placeholder={placeholder}
          autoComplete="off"
          onBlur={e => trimsValue(e.target.value)}
          rows={4}
          {...config}
        />,
      );
      break;
    }

    // 邮箱
    case 'email': {
      results = (
        <div className="st-email">
          {getFieldDecorator(item.id, getFieldParams())(
            <Input
              style={item.style || { width }}
              disabled={disabled}
              placeholder={placeholder}
              type={item.default || 'text'}
              size={size}
              autoComplete="off"
              allowClear={!item.options.disabled && allowClear}
              {...config}
            />,
          )}
          <Button loading={item.button.loading || false} onClick={() => item.button.callBack()}>
            {item.button.text}
          </Button>
        </div>
      );
      break;
    }

    // 日期组件 根据showTime字段来区分是否格式化到秒
    case 'daterange': {
      const showTime = item.options.showTime !== undefined ? item.options.showTime : false;
      const getWidth = () => {
        if (isMobile) {
          return '100%';
        }
        return showTime ? 380 : 260;
      };
      // 不能写多个三目运算。。。
      const widths = getWidth();

      results = getFieldDecorator(item.id, getFieldParams())(
        <DatePicker.RangePicker
          style={{ width: widths }}
          showTime={showTime}
          format={item.options.showTime ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'}
          // @ts-ignore
          disabledDate={disabledRangeDate}
          // @ts-ignore
          ranges={datePickRanges}
          allowClear={!item.options.disabled && allowClear}
          size={size}
          {...config}
        />,
      );
      break;
    }

    // 日期组件--月份
    case 'monthPicker': {
      const getWidth = () => {
        if (isMobile) {
          return '100%';
        }
        return 180;
      };
      const widths = getWidth();
      results = getFieldDecorator(item.id, getFieldParams())(
        // @ts-ignore
        <DatePicker.MonthPicker
          style={{ width: widths }}
          allowClear={!item.options.disabled && allowClear}
          size={size}
          format="YYYY-MM"
          {...config}
        />,
      );
      break;
    }

    // 日期组件-- 年
    case 'yearPicker': {
      const getWidth = () => {
        if (isMobile) {
          return '100%';
        }
        return 180;
      };
      const widths = getWidth();
      results = getFieldDecorator(item.id, getFieldParams())(
        // @ts-ignore
        <DatePicker
          style={{ width: widths }}
          allowClear={!item.options.disabled && allowClear}
          size={size}
          format="YYYY-MM-DD"
          {...config}
        />,
      );
      break;
    }

    // 查询
    case 'search': {
      const enterButton = item.options.enterButton ? (
        <div className="search-input">
          {item.options.loading && <Icon type="loading" />}
          <span>{item.options.enterButton}</span>
        </div>
      ) : (
        true
      );
      results = getFieldDecorator(item.id, getFieldParams())(
        <Input.Search
          style={item.style || { width }}
          disabled={disabled}
          placeholder={placeholder}
          type={item.default || 'text'}
          size={size}
          enterButton={enterButton}
          allowClear={!item.options.disabled && allowClear}
          onSearch={value => !item.options.loading && item.handle(value, formConfig.config)}
          onBlur={e => trimsValue(e.target.value)}
          autoComplete={autoComplete}
          {...config}
        />,
      );
      break;
    }

    // 下拉框
    case 'select': {
      results = getFieldDecorator(item.id, getFieldParams())(
        <Select
          style={item.style || { width }}
          size={size}
          disabled={disabled}
          showSearch={item.options.showSearch || false}
          placeholder={placeholder}
          // onChange={e => {
          //   item.options.callBack && item.options.callBack(e);
          // }}
          // filterOption={(input, option) =>
          //   option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
          // }
          allowClear={!item.options.disabled && allowClear}
          // select change事件的回掉
          onChange={value => {
            if (item.handle) item.handle(value, item);
          }}
          {...config}
        >
          {item.options.list.map((listItem: StateType) => {
            if (!listItem.hidden) {
              return (
                <Select.Option key={listItem.value} value={listItem.value}>
                  {listItem.label}
                </Select.Option>
              );
            }
            return null;
          })}
        </Select>,
      );
      break;
    }

    // 其他模版
    case 'template':
      results = item.options.template(item);
      break;
    default:
      break;
  }

  const formItemLayout = item.formItemLayout || {};

  // 排除父级样式影响
  if (exclude) {
    return results;
  }
  return (
    <Form.Item
      key={item.id}
      label={label}
      {...formItemLayout}
      className={classNames(formConfig.className, {
        'st-form-group': !formConfig.isPopup,
        'st-form-group-pop': formConfig.isPopup,
        'st-from-group-noLabel': !label,
      })}
    >
      {results}
      {item.options.icon && item.options.icon()}
    </Form.Item>
  );
};
